<template>
  <el-form
    ref="form"
    :model="rules"
    :rules="rulesData"
    label-width="120px"
    :validate-on-rule-change="false"
    class="form"
  >
    <el-form-item
      v-for="(item, index) in formData"
      :key="index"
      :label="item.label && item.label"
      :prop="item.prop && item.prop"
      v-if="!item.hidden"
      :class="[item.type === 'textarea' && 'el-textarea', item.class]"
      :title="item.label && item.label"
    >
      <template
        v-if="
          item.type === 'input' ||
          item.type === 'number' ||
          item.type === 'password' ||
          item.type === 'textarea'
        "
      >
        <div class="el-icon" v-if="item.icon"><img :src="item.icon" /></div>
        <el-input
          :type="item.type"
          :rows="item.rows && item.rows"
          v-model="rules[item.prop]"
          :placeholder="item.placeholder"
          :disabled="item.disabled && item.disabled"
          :readonly="item.readonly ? item.readonly : false"
          :maxlength="item.maxlength && item.maxlength"
          :show-word-limit="item.type === 'textarea' && true"
          @blur="item.blur && item.blur(rules[item.prop], rules)"
          @focus="item.focus && item.focus(rules[item.prop], rules)"
          @input="item.input && item.input(rules[item.prop], rules)"
          :class="[item.tips && 'left-tips']"
        />
        <div class="code-scope" v-if="item.isCode" @click="handleCode">
          <img @click="item.click(rules)" :src="item.url" />
        </div>
        <div
          class="el-scope"
          v-if="item.scope"
          @click="item.click(rules[item.prop])"
        >
          {{ item.scopeLabel }}
        </div>
        <div v-if="item.tips" class="input-tips" @click="item.click">
          {{ item.tips }}
        </div>
      </template>
      <template v-if="item.type === 'select'">
        <el-select
          v-model="rules[item.prop]"
          :placeholder="item.placeholder"
          :class="item.news && item.class"
          :disabled="item.disabled && item.disabled"
          :multiple="item.multiple ? true : false"
          @change="
            item.change && item.change(rules, rules[item.prop], parentKey)
          "
        >
          <el-option
            v-for="(option, index) in item.options"
            :key="index"
            :label="option.label"
            :value="option.value"
          />
        </el-select>
        <template
          v-if="
            rules[item.prop] == item.inputKey ||
            (rules[item.prop] &&
              Array.isArray(rules[item.prop]) &&
              rules[item.prop].includes(item.inputKey))
          "
        >
          <div style="margin: 10px 0 0">
            <el-input
              type="input"
              v-model="item.inputValue"
              :disabled="item.disabled && item.disabled"
              @input="
                (e) => {
                  item.input(e, item.inputKey);
                }
              "
            />
          </div>
        </template>
      </template>
      <template v-if="item.type === 'selectFilter'">
        <el-select
          v-model="rules[item.prop]"
          :multiple="item.multiple ? true : false"
          :disabled="item.disabled && item.disabled"
          filterable
          remote
          reserve-keyword
          :placeholder="item.placeholder ? item.placeholder : '请选择'"
          @change="item.change && item.change(item.value)"
          :remote-method="
            (query) => {
              remoteMethod(query, rules[item.prop]);
            }
          "
        >
          <el-option
            v-for="item in selectFilter"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          >
          </el-option>
        </el-select>
      </template>
      <template v-if="item.type === 'autocomplete'">
        <el-autocomplete
          v-model="rules[item.prop]"
          :fetch-suggestions="
            (queryString, cb) => {
              querySearchAsync(queryString, cb, item.autocompleteDate);
            }
          "
          :placeholder="item.placeholder"
          :disabled="item.disabled && item.disabled"
          @select="handleSelect"
        />
      </template>
      <template v-if="item.type === 'radio'">
        <el-radio-group
          v-model="rules[item.prop]"
          :disabled="item.disabled && item.disabled"
        >
          <el-radio
            :label="option.value"
            v-for="option in item.options"
            @change="item.change && item.change(rules[item.prop], rules)"
            :key="option.label"
            >{{ option.label }}</el-radio
          >
        </el-radio-group>
        <!-- <div
          class="others"
          style="width: 120px; display: inline-block"
          v-if="rules[item.prop] == 4"
        >
          <el-input type="input" v-model.trim="rules[item.newsProp]" />
        </div> -->
      </template>
      <template v-if="item.type === 'checkbox'">
        <el-checkbox-group v-model="rules[item.prop]">
          <el-checkbox
            :label="option.value"
            v-for="option in item.options"
            @change="item.change && item.change(rules[item.prop], rules)"
            :disabled="item.disabled && item.disabled"
            :key="option.label"
            >{{ option.label }}</el-checkbox
          >
        </el-checkbox-group>
      </template>
      <template v-if="item.type === 'date'">
        <el-date-picker
          v-model="rules[item.prop]"
          :disabled="item.disabled && item.disabled"
          :type="item.otherType ? item.otherType : 'date'"
          :picker-options="
            item.pickerOptions
              ? item.pickerOptions
              : item.limit && pickerOptions
          "
          :placeholder="item.placeholder"
          :value-format="item.format ? item.format : 'yyyy-MM-dd'"
          @change="item.change && item.change(rules[item.prop], rules)"
        />
      </template>
      <template v-if="item.type === 'daterange'">
        <el-date-picker
          v-model="rules[item.prop]"
          type="daterange"
          range-separator="-"
          :start-placeholder="
            item.startPlaceholder ? item.startPlaceholder : '开始日期'
          "
          :end-placeholder="
            item.endPlaceholder ? item.endPlaceholder : '结束日期'
          "
          :disabled="item.disabled && item.disabled"
          :value-format="item.format ? item.format : 'yyyy-MM-dd'"
          @change="
            item.change && item.change(rules[item.prop], rules, parentKey)
          "
        />

        <div v-if="item.tips" style="display: inline-block; margin: 0 0 0 5px">
          {{ item.tips }}
        </div>

        <template v-if="item.autocomplete">
          <el-autocomplete
            v-model="rules[item.newsProp]"
            :class="item.class"
            :fetch-suggestions="
              (queryString, cb) => {
                querySearchAsync(queryString, cb, item.autocompleteDate);
              }
            "
            :placeholder="item.newsPlaceholder"
            :disabled="item.disabled && item.disabled"
            @select="handleSelect"
          />
        </template>
      </template>
      <template v-if="item.type === 'datetime'">
        <el-date-picker
          v-model="rules[item.prop]"
          type="datetime"
          format="yyyy-MM-dd HH:mm"
          value-format="yyyy-MM-dd HH:mm"
          :placeholder="item.placeholder"
        />
      </template>
      <template v-if="item.type === 'time'">
        <el-time-picker
          :is-range="item.isRange"
          v-model="rules[item.prop]"
          range-separator="至"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          placeholder="选择时间范围"
          value-format="yyyy-MM-dd HH:mm"
        >
        </el-time-picker>
      </template>
      <template v-if="item.type === 'switch'">
        <el-switch
          v-model="rules[item.prop]"
          :active-text="item.activeText && item.activeText"
          :inactive-text="item.inactiveText && item.inactiveText"
        />
      </template>
      <template v-if="item.type === 'cascader'">
        <el-cascader
          size="large"
          :options="item.options"
          v-model="rules[item.prop]"
          :disabled="item.disabled && item.disabled"
          :placeholder="
            !item.disabled ? (item.label ? item.label : '请选择') : ''
          "
          @change="item.change && item.change"
        >
        </el-cascader>
      </template>
      <template v-if="item.type === 'wlTree'">
        <wlTreeSelect
          style="width: 100%"
          :checkbox="item.checkbox"
          :defaultExpandAll="false"
          :data="item.treeData"
          :props="item.props || { label: 'label', value: 'id' }"
          :nowrap="true"
          :checkStrictly="item.checkStrictly"
          class="t1"
          @change="
            (value) => {
              item.change(value, rules);
            }
          "
          v-model="item.value"
        />
      </template>
      <template v-if="item.type === 'upload'">
        <Upload
          :uploadData="{
            single: item.single,
            limit: item.limit,
            list: rules[item.prop] ? rules[item.prop] : [],
            size: item.size,
            api: item.api,
            onChange: (value) => {
              item.onChange(value, rules);
            },
          }"
        />
      </template>
      <template v-if="item.type === 'uploadFile'">
        <UploadFile
          :uploadData="{
            list: rules[item.prop] ? rules[item.prop] : [],
            disabled: item.disabled,
            limit: item.limit,
            onChange: (e) => {
              uploadFileChange(e, item);
            },
            api: item.api,
          }"
        />
      </template>
      <template v-if="item.type === 'editor'">
        <div
          v-if="item.disabled"
          v-html="rules[item.prop]"
          class="editor-content"
        ></div>
        <Editor
          :editorData="rules[item.prop]"
          v-else
          @onChange="
            (value) => {
              rules[item.prop] = value;
              item.onChange(rules[item.prop], rules);
            }
          "
        />
      </template>
      <template v-if="item.type === 'txt'">
        <el-row v-html="rules[item.prop]" class="txt-warp"></el-row>
      </template>
      <template v-if="item.type === 'tree'">
        <div @click="handleShow(item.prop)">
          <el-input
            :placeholder="item.placeholder"
            :readonly="true"
            :disabled="item.disabled && item.disabled"
            v-model="item.value"
          />
        </div>
        <template v-if="treeStatus[item.prop]">
          <div class="tree-modle" @click="handleClose(item.prop)"></div>
          <div class="filter-tree">
            <el-tree
              :data="item.treeData"
              :expand-on-click-node="false"
              @current-change="
                (value, data) =>
                  item.click(value, data, rules) ||
                  handleNodeClick(item.prop, value, item.limit)
              "
            />
          </div>
        </template>
      </template>

      <template v-if="item.type === 'custom'">
        <component v-if="item.components" :is="item.components" ref="custom" />
        <slot :name="item.slotName" :data="item"></slot>
      </template>

      <template v-if="item.type === 'button'">
        <el-button :type="item.class" @click="item.onlick(formData)">{{
          item.label
        }}</el-button>
      </template>
    </el-form-item>
    <el-form-item class="btns" v-if="formBtns && formBtns.length">
      <el-button
        v-for="(item, index) in formBtns"
        :key="index"
        :type="item.type && item.type"
        v-if="!item.hidden"
        @keyup.enter.native="
          item.isVerify ? handleSubmit('form') : item.click()
        "
        @click="item.isVerify ? handleSubmit('form') : item.click()"
        >{{ item.label }}</el-button
      >
    </el-form-item>
  </el-form>
</template>
<script>
import { Rule } from "@/utils/rule.js";
import Upload from "@/components/upload/index.vue";
// import Editor from "@/components/editor.vue";
import UploadFile from "@/components/uploadFile/index.vue";
export default {
  components: {
    Upload,
    // Editor,
    UploadFile,
  },
  data() {
    return {
      treeStatus: {}, //树结构数据
      datas: {}, //返回父级数据
      rules: {}, //重构数据对象
      sendAuthCode: true, //验证码发送状态
      authTime: 60, //倒计时时间
      autocompleteDate: [], //匹配搜索数组 input 远程搜索
      selectFilterAll: [], //匹配搜索数组 select 远程搜索 所有数据
      selectFilter: [], //匹配搜索数组 select 远程搜索 匹配到的数据
      pickerOptions: {
        //日期限制内容
        disabledDate(time) {
          return time.getTime() >= new Date().getTime();
        },
      },
    };
  },
  props: ["formData", "rulesData", "formBtns", "parentKey"],
  watch: {
    rules: {
      handler(news, old) {
        this.datas = news;
      },
      deep: true,
    },
    formData: {
      handler(news, old) {
        if (news) {
          this.formData = news;
          this.getRules();
        }
      },
      deep: true,
    },
  },
  created() {
    this.getMethod();
    this.getRules();
  },
  methods: {
    //赋值搜索
    getMethod() {
      if (this.formData && this.formData.length > 0) {
        this.formData.forEach((item) => {
          if (item.type === "selectFilter") {
            this.selectFilter = item.options;
            this.selectFilterAll = item.options;
          }
        });
      }
    },
    //校验表单的数据项
    getRules() {
      if (this.formData.length > 0) {
        this.formData.forEach((item) => {
          this.rules = Object.assign({}, this.rules, {
            [item.prop]: item.value || item.value === 0 ? item.value : "",
          });
          if (item.newsProp) {
            this.rules = Object.assign({}, this.rules, {
              [item.newsProp]:
                item.value || item.value === 0 ? item.newsValue : "",
            });
          }
        });
      }
    },
    //验证码倒计时
    handleCode() {
      // if (this.sendAuthCode) {
      //   this.AuthCode();
      // }
    },
    //提交
    handleSubmit(form) {
      this.$refs[form].validate((valid) => {
        if (valid) {
          Object.keys(this.datas).forEach((item) => {
            if (
              typeof this.datas[item] == "string" &&
              this.datas[item].constructor == String
            ) {
              this.datas[item] = this.datas[item].trim();
            }
          });
          this.$emit("handleSubmit", this.datas);
        }
      });
    },
    //搜索过滤
    remoteMethod(query, array) {
      if (query !== "") {
        this.selectFilter = this.selectFilterAll;
        setTimeout(() => {
          this.selectFilter = this.selectFilter.filter((item) => {
            return (
              item.label.toLowerCase().indexOf(query.toLowerCase()) > -1 ||
              (array && array.includes(item.value))
            );
          });
        }, 200);
      } else {
        this.selectFilter = this.selectFilterAll;
      }
    },
    //模糊搜索
    querySearchAsync(queryString, cb, autocompleteDate) {
      if (autocompleteDate) {
        this.autocompleteDate = autocompleteDate;
      }
      var restaurants = this.autocompleteDate;
      var results = queryString
        ? restaurants.filter(this.createStateFilter(queryString))
        : restaurants;
      clearTimeout(this.timeout);
      this.timeout = setTimeout(() => {
        cb(results);
      }, 1000 * Math.random());
    },
    createStateFilter(queryString) {
      return (state) => {
        return (
          state.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
        );
      };
    },
    //选择模糊搜索内容
    handleSelect(item) {},
    //选择树节点
    handleNodeClick(key, data, limit) {
      if (!data.children || limit) {
        this.rules[key] = data.label;
        this.$set(this.treeStatus, key, false);
      }
    },
    //隐藏表单树
    handleClose(key) {
      setTimeout(() => {
        this.$set(this.treeStatus, key, false);
      }, 200);
    },
    //展开表单树
    handleShow(key) {
      this.$set(this.treeStatus, key, true);
    },

    //
    uploadFileChange(e, item) {
      this.datas = { ...this.datas, [item.prop]: e };
      item.onChange(e);
    },
  },
};
</script>

<style scoped lang="scss">
.el-scope {
  position: absolute;
  right: 0;
  top: 0;
  width: 100px;
  text-align: center;
  background: #00bda1;
  color: #fff;
  border-radius: 0 5px 5px 0;
  cursor: pointer;
  &:hover {
    opacity: 0.6;
  }
}
.el-cascader {
  width: 100%;
}
.editor-content {
  height: 500px;
  background: #f8f8f8;
  padding: 0 10px;
}
</style>
<style lang="scss">
.left-tips {
  width: calc(100% - 160px);
}
.form {
  display: inline-block;
  width: 100%;
  position: relative;
  margin-bottom: 20px;
  padding-bottom: 5px;
  .el-select,
  .el-date-editor {
    width: 100% !important;
  }
  &::after {
    content: "";
    width: calc(100% + 40px);
    position: absolute;
    left: -20px;
    bottom: -20px;
    // border-bottom: solid 20px #f7f8fa;
  }
  .title {
    font-size: 15px;
    font-weight: 600;
    color: #1d2129;
  }
  .mt20 {
    margin-top: 20px;
  }
  .el-form-item {
    width: 50%;
    float: left;
  }
  .form {
    width: calc(100% - 60px);
  }
  .el-form-item__label {
    width: 140px !important;
  }
  .el-form-item__content {
    margin-left: 140px !important;
  }
  .btns {
    width: 100%;
    text-align: right;
  }
}
.options-btns {
  padding: 0 30px;

  text-align: right;
}
.wl-tree-select {
  min-width: 260px;
}
</style>
